package com.qitianyong.selfclass;

import android.hardware.usb.UsbDeviceConnection;
import android.os.Build;
import android.util.Log;

import com.gkusbsdk.GKUSBCommand;
import com.gkusbsdk.GKUSBFile;
import com.gkusbsdk.GKUSBFileInfo;
import com.gkusbsdk.GKUSBFireware;
import com.gkusbsdk.GKUSBFormat;
import com.gkusbsdk.GKUSBIFrame;
import com.gkusbsdk.GKUSBRecordDate;
import com.gkusbsdk.GKUSBResolution;
import com.gkusbsdk.GKUSBSDK;
import com.ligo.log.util.ZyLog;
import com.qitianyong.sgkusbcamera.PreviewActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;

/**
 * Created by qitianyong on 2017/3/15.
 * 所有的USB传输从此类走
 * 指令处理通过三个主体线程：
 * 1.插拔状态检测线程
 * 2.基本指令传输线程
 * 3.普通状态检测线程（SD是否存在，录像状态，预览时紧急视频加锁状态和进度）
 */
public class GKDevice extends BaseClass {

    private boolean[] __bThreadStatus = new boolean[]{true, true, true}; // 线程状态
    private Thread[] __thread = new Thread[CONSTANT.THREAD_ID.ID_COUNT]; // 线程数组

    public static long __hDevice = 0; // 设备句柄
    public static boolean openStreamStatus = false; // 设备句柄
    public static UsbDeviceConnection usbConnection; // USB设备连接
    public static GKDevice __device = null;

    private GKUSBFireware fireware;
    public int __exit = CONSTANT.THREAD_ID.ID_COUNT; // 当前还活着的线程个数

    // 数据存储链表
    private List<CommandMessage> __cmdList = new ArrayList<>(); // 指令信息列表
    private GKUSBFormat[] __format = new GKUSBFormat[32];
    private int __format_count = 0;
    private GKUSBRecordDate __lastDate;

    private List<GKUSBFile> __fileNameList = new ArrayList(); // 存储GKUSBFile
    private List __list;

    private Lock __lock = CustomApp.__lock;  // 指令发送互斥锁
    private final GKUSBCmdList __gkusbCmdList;

    public static GKDevice getInstance() {

        if (__device == null) {
            __device = new GKDevice();
        }

        return __device;
    }

    public GKDevice() {

        __gkusbCmdList = new GKUSBCmdList();
        // 开启3大主线程
        __thread[CONSTANT.THREAD_ID.ID_CHECK_ONLINE] = new Thread(checkOnlineRunnable);
        __thread[CONSTANT.THREAD_ID.ID_COMMAND] = new Thread(commandRunnable);
        __thread[CONSTANT.THREAD_ID.ID_STATUS] = new Thread(statusRunnable);

        __thread[CONSTANT.THREAD_ID.ID_CHECK_ONLINE].start();
        __thread[CONSTANT.THREAD_ID.ID_COMMAND].start();
        __thread[CONSTANT.THREAD_ID.ID_STATUS].start();
    }

    // 销毁设备
    public void Destroy() {

        // 置线程标志退出线程
        for (int i = 0; i < CONSTANT.THREAD_ID.ID_COUNT; i++) {
            __bThreadStatus[i] = false;
        }
        final boolean[] isDestroyed = {false};
        //watch dog
        new Thread(new Runnable() {
            @Override
            public void run() {
                PublicMethod.sleep(4500);
                if (!isDestroyed[0]) {
                    System.exit(0);
                }
            }
        }).start();
        while (__exit != 0) { // 等待线程完全退出后销毁设备

            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        Log.i("GKDevice", "destroy device");

        // 销毁设备
        if (__hDevice != 0) {

            __lock.lock();

            GKUSBSDK.GKUSB_SetProtocol(__hDevice, GKUSBCommand.PROTOCOL_TYPE.TYPE_OLD);
            openStreamStatus = false;
            GKUSBSDK.GKUSB_CloseStream(__hDevice);
            GKUSBSDK.GKUSB_Destroy(__hDevice);
            if (usbConnection != null) {
                usbConnection.close();
                usbConnection = null;
            }
            isDestroyed[0] = true;
            __hDevice = 0;
            __lock.unlock();
        }
        System.exit(0);
        __device = null;
    }

    // 设置数据流回调
    public void setCallback(GKUSBSDK.CallBack cb) {

        GKUSBSDK.setCallback(cb);
    }

    // 发送USB指令
    public int sendCommand(int command, Object message) {
        if (__hDevice == 0) {
            notifyEmptyBusMessage(BUS_MESSAGE.BUS_PRINT);
            return -1;
        }

        __gkusbCmdList.addCommand(command, message);

        return 0;
    }

    public int sendCommandsNoRepeated(int command, List messages) {
        if (__hDevice == 0) {
            notifyEmptyBusMessage(BUS_MESSAGE.BUS_PRINT);
            return -1;
        }

        __gkusbCmdList.addCommandNoRepeated(command, messages);

        return 0;
    }

    // 发送USB指令到列表的第一个,去重
    public int sendCommandAddToFirstNoRepeated(int command, Object message) {
        if (__hDevice == 0) {
            notifyEmptyBusMessage(BUS_MESSAGE.BUS_PRINT);
            return -1;
        }

        __gkusbCmdList.addToFirstNoRepeated(command, message);

        return 0;
    }

    public void clearSpeciallyTypeCommand(int type) {
        __gkusbCmdList.clearSpeciallyTypeCommand(type);
    }

    // 获取下一批文件信息
    public int GetNextFiles(int current, int expect_total) {
        if (__hDevice == 0) {
            notifyEmptyBusMessage(BUS_MESSAGE.BUS_PRINT);
            return -1;
        }
        //去掉下载预览图文件 防止堵塞
//        GKDevice.getInstance().clearSpeciallyTypeCommand( CONSTANT.COMMAND.CMD_GET_PHOTO);

        int i = 0;
        for (i = current; i < current + expect_total; i++) {
            int size = __fileNameList.size();
            if (size > i) {
                GKUSBFile usbFile = __fileNameList.get(i);
                sendCommandAddToFirstNoRepeated(CONSTANT.COMMAND.CMD_GET_FILEINFO, usbFile);
                Log.i("getfileinfo", "count:" + i + " current:" + current + " expect:" + expect_total);
            } else {
                break;
            }
        }

        return i - current;
    }

    public void getFileImg() {
        ArrayList gkusbFiles = new ArrayList();
        for (int i = 0; i < __list.size(); i++) {
            if (__list.get(i) instanceof GKUSBFileInfo) {
                GKUSBFileInfo gkusbFileInfo = (GKUSBFileInfo) __list.get(i);
                byte[] bytes = gkusbFileInfo.__type == GKUSBCommand.FILE_TYPE.PHOTO_FILE ? gkusbFileInfo.__name : gkusbFileInfo.__thumb_name;
                String key = null;
                if (bytes != null) {
                    key = new String(bytes);
                }
                if (!CustomApp.__lruCacheHelper.isCachedImg(key, -1, -1)) {
                    gkusbFiles.add(gkusbFileInfo);
                }
            }
        }
        GKDevice.getInstance().sendCommandsNoRepeated(CONSTANT.COMMAND.CMD_GET_PHOTO, gkusbFiles);

    }

    // 设置文件信息列表
    public void setUSBFileInfoList(List<Object> list) {
        __list = list;
        __lastDate = null;
    }

    // 在线监测线程
    private Runnable checkOnlineRunnable = new Runnable() {
        @Override
        public void run() {
            while (__bThreadStatus[CONSTANT.THREAD_ID.ID_CHECK_ONLINE]) {

                //Log.i("GKDevice", "------hDevice:"+__hDevice);
                if (__hDevice == 0) {
                    PublicMethod.sleep(1);
                    continue;
                }
                __lock.lock();

                if (__hDevice != 0) {
                    int online = GKUSBSDK.GKUSB_GetOnlineStatus(__hDevice);
                    ZyLog.d("GKUSB_GetOnlineStatus =" + online);
                    if (online == 0) {

                        Log.i("GKDevice", "disconnect---1");
                        openStreamStatus = false;
                        GKUSBSDK.GKUSB_CloseStream(__hDevice);
                        GKUSBSDK.GKUSB_Destroy(__hDevice);
                        __hDevice = 0;
                        if (usbConnection != null) {
                            usbConnection.close();
                            usbConnection = null;
                        }
                        if ((FindDeviceThread.lastConnectTime - System.currentTimeMillis()) < 10000) {
                            FindDeviceThread.getInstance().setIntent(FindDeviceThread.OPEN_APP);
                        }
                        notifyEmptyBusMessage(BUS_MESSAGE.BUS_OFFLINE);
                    } else {
                        if (GKUSBSDK.getCallback() instanceof PreviewActivity) {
//                            ZyLog.d("PreviewActivity.lastPreviewActivityUpdateTime=" + (PreviewActivity.lastPreviewActivityUpdateTime + 5000) + " currentTimeMillis=" + System.currentTimeMillis());
                            if (PreviewActivity.lastPreviewActivityUpdateTime + 15000 < System.currentTimeMillis() && openStreamStatus) {
//                                Log.i("GKDevice", "disconnect---lastPreviewActivityUpdateTime");
                                ZyLog.d("disconnect---lastPreviewActivityUpdateTime");
                                openStreamStatus = false;
                                GKUSBSDK.GKUSB_CloseStream(__hDevice);
                                GKUSBSDK.GKUSB_Destroy(__hDevice);
                                __hDevice = 0;
                                if (usbConnection != null) {
                                    usbConnection.close();
                                    usbConnection = null;
                                }
                                FindDeviceThread.getInstance().setIntent(FindDeviceThread.OPEN_APP);
                                notifyEmptyBusMessage(BUS_MESSAGE.BUS_OFFLINE);
                            }
                        }
                    }
                }

                __lock.unlock();

                PublicMethod.sleep(1000);
            }

            __lock.lock();
            __exit--;
            __lock.unlock();
            Log.i("GKDevice", "Exit checkonline thread");
        }
    };

    // 指令消息的处理
    private void HandleMessage(CommandMessage msg) {

        if (__hDevice == 0 || msg == null) return;
        ZyLog.d("HandleMessage = " + msg.command);
        switch (msg.command) {
            case CONSTANT.COMMAND.CMD_ALL_FORMAT: { // 获取设备支持的格式
//                __format_count = GKUSBSDK.GKUSB_GetSupportFormat(__hDevice, __format);
//                notifyBusMessage(CONSTANT.COMMAND.CMD_ALL_FORMAT, __format_count);
            }
            break;
            case CONSTANT.COMMAND.CMD_OPEN_STREAM: {// 开启预览
                fireware = new GKUSBFireware();
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_RECORD_VERSION, fireware);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_GetParam CMD_RECORD_VERSION ret=" + ret);
                GKUSBResolution objResolution = new GKUSBResolution();

                if (fireware.__product_type == GKUSBCommand.PRODUCT_TYPE.GK8602_A) {
                    objResolution.__width = 1920;
                    objResolution.__height = 1080;
                } else {
                    objResolution.__width = 1280;
                    objResolution.__height = 720;
                }
                ZyLog.d("CONSTANT.COMMAND.CMD_OPEN_STREAM " + objResolution.toString());
                GKUSBFormat objFormat = new GKUSBFormat();
                objFormat.__format = GKUSBCommand.STREAM_FORMAT.H264;//GKUSBCommand.STREAM_FORMAT.MJPEG;

                PublicMethod.sleep(200);

                long open = GKUSBSDK.GKUSB_OpenStream(__hDevice, objFormat, objResolution);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_OpenStream ret=" + ret);
                //返回值为-51时，表示格式错误。为兼容老版本 720p A板的设备 ，重新开一次流，参数改为720p
                if (open == -51 && fireware.__product_type == GKUSBCommand.PRODUCT_TYPE.GK8602_A) {
                    objResolution.__width = 1280;
                    objResolution.__height = 720;
                    PublicMethod.sleep(500);
                    open = GKUSBSDK.GKUSB_OpenStream(__hDevice, objFormat, objResolution);
                    if (open == -51) {
                        open = 0;
                    }
                }
                if (open == -51) {
                    open = 0;
                }
                if (open == 0) { // 开启失败后重新检测

                    openStreamStatus = false;
                    GKUSBSDK.GKUSB_CloseStream(__hDevice);
                    GKUSBSDK.GKUSB_Destroy(__hDevice);
                    __hDevice = 0;
                    if (usbConnection != null) {

                        usbConnection.close();
                        usbConnection = null;
                    }
                    FindDeviceThread.getInstance().setIntent(FindDeviceThread.OPEN_APP);
                    Log.i("GKDevice", "disconnect---2");
                } else {
                    openStreamStatus = true;
                    notifyEmptyBusMessage(BUS_MESSAGE.BUS_OPENSTREAM_OK);
                    ZyLog.d("CONSTANT.COMMAND.BUS_OPENSTREAM_OK ");
                    Log.i("GKDevice", "BUS_OPENSTREAM_OK");
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_START_STREAM:
                GKUSBResolution objResolution = new GKUSBResolution();
                if (null == fireware) {
                    fireware = new GKUSBFireware();
                    int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_RECORD_VERSION, fireware);
                }
                if (fireware.__product_type == GKUSBCommand.PRODUCT_TYPE.GK8602_A) {
                    objResolution.__width = 1920;
                    objResolution.__height = 1080;
                } else {
                    objResolution.__width = 1280;
                    objResolution.__height = 720;
                }
                ZyLog.d("CONSTANT.COMMAND.CMD_OPEN_STREAM " + objResolution.toString());
                GKUSBFormat objFormat = new GKUSBFormat();
                objFormat.__format = GKUSBCommand.STREAM_FORMAT.H264;//GKUSBCommand.STREAM_FORMAT.MJPEG;
                PublicMethod.sleep(200);

                long open = GKUSBSDK.GKUSB_OpenStream(__hDevice, objFormat, objResolution);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_OpenStream open=" + open);
                //返回值为-51时，表示格式错误。为兼容老版本 720p A板的设备 ，重新开一次流，参数改为720p
                if (open == -51 && fireware.__product_type == GKUSBCommand.PRODUCT_TYPE.GK8602_A) {
                    objResolution.__width = 1280;
                    objResolution.__height = 720;
                    PublicMethod.sleep(500);
                    open = GKUSBSDK.GKUSB_OpenStream(__hDevice, objFormat, objResolution);
                    ZyLog.d("CONSTANT.COMMAND.GKUSB_OpenStream open1=" + open);
                    if (open == -51) {
                        open = 0;
                    }
                }
                if (open == -51) {
                    open = 0;
                }
                break;
            case CONSTANT.COMMAND.CMD_STOP_STREAM:
                int closeRet = GKUSBSDK.GKUSB_CloseStream(__hDevice);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_CloseStream closeRet=" + closeRet);
                break;
            case CONSTANT.COMMAND.CMD_GETRECORD_STATUS: { // 获取录像状态
                int status = GKUSBSDK.GKUSB_GetRecordStatus(__hDevice);
                ZyLog.d("CONSTANT.COMMAND.CMD_GETRECORD_STATUS status=" + status);
                notifyBusMessage(BUS_MESSAGE.BUS_GETRECORD_STATUS, status); // status值-1和STATUS_RECORD
                break;
            }
            case CONSTANT.COMMAND.CMD_SETRECORD_STATUS: { // 设置录像状态
                int status = GKUSBSDK.GKUSB_GetRecordStatus(__hDevice);
                ZyLog.d("CONSTANT.COMMAND.CMD_SETRECORD_STATUS status=" + status);
                if (status == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_SETRECORD_STATUS, -1); // status值-1表示失败
                    break;
                }

                status = (status == 0) ? 1 : 0;
                int ret = GKUSBSDK.GKUSB_SetRecordStatus(__hDevice, status);
                notifyBusMessage(BUS_MESSAGE.BUS_SETRECORD_STATUS, ret); // ret为0成功，否则失败
                break;
            }
            case CONSTANT.COMMAND.CMD_SYNC_TIME: { // 时间同步
                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_SYNC_TIME, msg.message);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_SetParam CMD_SYNC_TIME ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_SYNC_TIME, ret); // ret为0成功，否则失败
                System.out.println("CMD_SYNC_TIME" + ret);
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_RECORD_TIME: { // 获取录像时长
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_RECORD_TIME");
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_RECORDTIME_CTRL, null);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_SetParam CMD_RECORDTIME_CTRL ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_GET_RECORD_TIME, ret); // ret为-1：失败，RESULT_RECORDTIME
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_SENSOR: { // 获取g-sensor等级
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_GSENSOR, null);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_SENSOR ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_GET_SENSOR, ret); // ret为-1：失败，RESULT_LEVER
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_RECORD_AUTO_MANAL: { // 获取手动/自动录像开关
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_RECORD_AUTO_MANAL, null);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_RECORD_AUTO_MANAL ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_GET_RECORD_AUTO_MANAL, ret);// ret为-1：失败，GKUSBNormal
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_RECORD_AUDIO: {// 获取录制音频开关
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_AUDIO_RECORD, null);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_RECORD_AUDIO ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_GET_RECORD_AUDIO, ret); //ret为-1：失败，SWITCH
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_SDCARD_FORMAT: { // 获取SD卡格式化进度
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_SDFORMAT, null);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_SDCARD_FORMAT ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_GET_SDCARD_FORMAT, ret); // ret为-1:失败 否则0~100进度
                Log.i("format", "-----ret:" + ret);
                break;
            }
            case CONSTANT.COMMAND.CMD_DEFAULT_FACTORY: { // 恢复出厂设置
                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_DEFAULT_FACTORY, null);
                ZyLog.d("CONSTANT.COMMAND.CMD_DEFAULT_FACTORY ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_DEFAULT_FACTORY, ret); // ret为-1:失败 否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_RECORDER_VERSION: { // 获取固件版本
                GKUSBFireware fireware = new GKUSBFireware();
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_RECORD_VERSION, fireware);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_RECORDER_VERSION ret=" + ret);
                if (ret == -1) {
                    notifyEmptyBusMessage(BUS_MESSAGE.BUS_GET_RECORDER_VERSION_ERR); // 失败
                } else {
                    Log.i("GKDevice", new String(fireware.__version) + " len:" + fireware.__version.length);
                    notifyBusMessage(BUS_MESSAGE.BUS_GET_RECORDER_VERSION_OK, fireware); // 成功，GKUSBFireware
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_RESOLUTION: { // 获取当前分辨率
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_RESOLUTION_CTRL, null);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_RESOLUTION ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_GET_RESOLUTION, ret); // -1:失败 否则：RESULT_RESOLUTION
                break;
            }
            case CONSTANT.COMMAND.CMD_SET_RECORD_TIME: { // 设置录像时长
                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_RECORDTIME_CTRL, msg.message);
                ZyLog.d("CONSTANT.COMMAND.CMD_SET_RECORD_TIME ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_SET_RECORD_TIME, ret); // -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_SET_SENSOR: { // 设置g-sensor等级
                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_GSENSOR, msg.message);
                ZyLog.d("CONSTANT.COMMAND.CMD_SET_SENSOR ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_SET_SENSOR, ret); // -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_SET_RECORD_AUTO_MANAL: { // 设置自动/手动录像

                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_RECORD_AUTO_MANAL, msg.message);
                ZyLog.d("CONSTANT.COMMAND.CMD_SET_RECORD_AUTO_MANAL ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_SET_RECORD_AUTO_MANAL, ret); // -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_SET_RECORD_AUDIO: { // 设置音频录制开关

                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_AUDIO_RECORD, msg.message);
                ZyLog.d("CONSTANT.COMMAND.CMD_SET_RECORD_AUDIO ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_SET_RECORD_AUDIO, ret);// -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_SET_RESOLUTION: { // 设置分辨率

                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_RESOLUTION_CTRL, msg.message);
                ZyLog.d("CONSTANT.COMMAND.CMD_SET_RESOLUTION ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_SET_RESOLUTION, ret);// -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_SET_SDCARD_FORMAT: {   // 设置SD卡格式

                int ret = GKUSBSDK.GKUSB_SetParam(__hDevice, GKUSBCommand.CMD_SDFORMAT, msg.message);
                ZyLog.d("CONSTANT.COMMAND.CMD_SET_SDCARD_FORMAT ret=" + ret);
                PublicMethod.sleep(1000); // 格式化指令发送后获取进度需要延时1秒，给设备关闭录像足够时间
                notifyBusMessage(BUS_MESSAGE.BUS_SET_SDCARD_FORMAT, ret);// -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_SEARCH_FILE: { // 搜索所有的文件名
                notifyEmptyBusMessage(BUS_MESSAGE.BUS_CLEAR_FILELIST);
                __fileNameList.clear();

                long sTime = PublicMethod.getCurrentMillis();
                GKUSBFile[] usbFileArr = new GKUSBFile[CONSTANT.MAX_FILES];
                int count = GKUSBSDK.GKUSB_SearchFileName(__hDevice, (int) msg.message, usbFileArr);
                ZyLog.d("CONSTANT.COMMAND.CMD_SEARCH_FILE count=" + count);
                long eTime = PublicMethod.getCurrentMillis();

                Log.i("mytime", "search time:" + (eTime - sTime));

                if (__fileNameList != null) {
                    for (int i = 0; i < count; i++) {
                        usbFileArr[i].__lock = (int) msg.message;
                        __fileNameList.add(usbFileArr[i]);
                        //Log.i("getfileinfo", "-------file["+i+"]:"+new String(usbFileArr[i].__name));
                    }
                }

                notifyBusMessage(BUS_MESSAGE.BUS_SEARCH_COMPLETE, count);// -1失败，否则成功
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_FILEINFO: { // 获取文件信息

                GKUSBFile usbFile = (GKUSBFile) msg.message;
                String name = new String(usbFile.__name) + '\0';

                GKUSBFileInfo usbFileInfo = null;
                if (usbFile.__lock != GKUSBCommand.FILE_TYPE.PHOTO_FILE) {
                    long sTime = PublicMethod.getCurrentMillis();
                    usbFileInfo = (GKUSBFileInfo) GKUSBSDK.GKUSB_GetFileInfoEx(__hDevice, usbFile.__lock, name.getBytes());
                    long eTime = PublicMethod.getCurrentMillis();
                    ZyLog.d("CONSTANT.COMMAND.CMD_GET_FILEINFO name=" + name + "  period:" + (eTime - sTime));
//                    Log.i("mytime", "name:"+name+" period:"+(eTime-sTime));
                }
                //时长为0的无效文件 不添加日期
                if (usbFileInfo == null || usbFileInfo.__duration != 0) {
                    GKUSBRecordDate date = PublicMethod.parseString2RecordDate(new String(usbFile.__name));

                    if (__lastDate == null || __lastDate.__year != date.__year || __lastDate.__month != date.__month || __lastDate.__day != date.__day) {

                        __lastDate = date;
                        __list.add(date);
                    }

                }

                if (usbFileInfo == null) {
                    Log.i("usbFile", "type:" + usbFile.__lock + " " + name + " get file info err len:" + usbFile.__name.length);
                    usbFileInfo = new GKUSBFileInfo();
                    usbFileInfo.__type = usbFile.__lock;
                    System.arraycopy(usbFile.__name, 0, usbFileInfo.__name, 0, usbFile.__name.length);
                    __list.add(usbFileInfo);
                } else if (usbFileInfo.__duration != 0) {
                    usbFileInfo.__type = usbFile.__lock;
                    __list.add(usbFileInfo);
                }
                //Log.i("usbFile", "type:" + usbFile.__lock + "[" + new String(usbFileInfo.__name) + "]:" + usbFileInfo.__duration + "" +
                //            "thumb:" + new String(usbFileInfo.__thumb_name));

                notifyEmptyBusMessage(BUS_MESSAGE.BUS_FILEINFO_OK);
                break;
            }
            case CONSTANT.COMMAND.CMD_FILE_CONTROL: { // 文件的控制(视频/音频)

                GKUSBFile file = (GKUSBFile) msg.message;
                String name = new String(file.__name) + '\0';
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__lock, file.__command, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_FILE_CONTROL ret=" + ret);
                if (ret == -1 || ret == 1) {// 失败
                    notifyBusMessage(BUS_MESSAGE.BUS_CONTROL_ERR, file);
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_CONTROL_OK, file);
                }

                break;
            }
            case CONSTANT.COMMAND.CMD_PLAYBACK_PROGRESS: { // 获取播放进度

                int curTime = GKUSBSDK.GKUSB_GetCurrentPlaybackTime(__hDevice);
                ZyLog.d("CONSTANT.COMMAND.CMD_FILE_CONTROL curTime=" + curTime);
                if (curTime != -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_PLAYBACK_PROGRESS, curTime);
                }

                break;
            }
            case CONSTANT.COMMAND.CMD_GETLOCK_PROGRESS: { // 获取加锁进度
                int ret = GKUSBSDK.GKUSB_GetCurrentStatus(__hDevice, GKUSBCommand.STATUS_CONTROL.STATUS_HURRY_FINISH);
                ZyLog.d("CONSTANT.COMMAND.CMD_GETLOCK_PROGRESS ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_RECORD_HURRY, ret);
                break;
            }
            case CONSTANT.COMMAND.CMD_DELETE_PHOTO: {

                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';
                // Log.i("GKDevice","CMD_DELETE_PHOTO type:"+file.__type+" name:"+name);
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.PHOTO_FILE_CONTROL.CONTROL_DELETE, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_DELETE_PHOTO ret=" + ret);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_DELETE_PHOTO_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_DELETE_PHOTO, ret);
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_DELETE_VIDEO: {

                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';
                // Log.i("GKDevice","CMD_DELETE_VIDEO type:"+file.__type+" name:"+name);
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_DELETE, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_DELETE_VIDEO ret=" + ret);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_DELETE_VIDEO_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_DELETE_VIDEO, ret);
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_LOCK_VIDEO: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';
                //Log.i("GKDevice","CMD_LOCK_VIDEO type:"+file.__type+" name:"+name);
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_LOCK, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_LOCK_VIDEO ret=" + ret);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_LOCK_VIDEO_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_LOCK_VIDEO, ret);
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_UNLOCK_VIDEO: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';
                //Log.i("GKDevice","CMD_LOCK_VIDEO type:"+file.__type+" name:"+name);
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_UNLOCK, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_UNLOCK_VIDEO ret=" + ret);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_UNLOCK_VIDEO_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_UNLOCK_VIDEO, ret);
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_PLAYBACK: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';
                //Log.i("GKDevice","CMD_LOCK_VIDEO type:"+file.__type+" name:"+name);
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_PLAY, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_PLAYBACK ret=" + ret + "  name=" + name);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_PLAYBACK_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_PLAYBACK, ret);
                }
                Log.i("GKDevice", "CMD_PLAYBACK ret:" + ret + " name:" + name);
                break;
            }
            case CONSTANT.COMMAND.CMD_STOP_PLAYBACK: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';

                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_STOP, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_STOP_PLAYBACK ret=" + ret + "  name=" + name);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_STOP_PLAYBACK_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_STOP_PLAYBACK, ret);
                }
                Log.i("GKDevice", "CMD_STOP_PLAYBACK ret:" + ret + " name:" + name);
                break;
            }
            case CONSTANT.COMMAND.CMD_ENTER_FILELIST: {
                Log.i("filelist", "-------enter filelist");
                if (Build.MODEL.toLowerCase().contains("sofia") || Build.MODEL.toLowerCase().contains("k1s")) {
                    notifyBusMessage(BUS_MESSAGE.BUS_ENTER_FILELIST, 1);
                    break;
                }
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, GKUSBCommand.FILE_TYPE.CYCLE_FILE, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_ENTER_FILELIST, new byte[]{});
                ZyLog.d("CONSTANT.COMMAND.CMD_ENTER_FILELIST ret=" + ret);
                Log.i("filelist", "-------ret:" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_ENTER_FILELIST, ret);
                break;
            }
            case CONSTANT.COMMAND.CMD_EXIT_FILELIST: {
                Log.i("filelist", "-------exit filelist");
                if (Build.MODEL.toLowerCase().contains("sofia") || Build.MODEL.toLowerCase().contains("k1s")) {
                    notifyBusMessage(BUS_MESSAGE.BUS_EXIT_FILELIST, 1);
                    break;
                }
                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, GKUSBCommand.FILE_TYPE.CYCLE_FILE, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_EXIT_FILELIST, new byte[]{});
                Log.i("filelist", "-------ret:" + ret);
                ZyLog.d("CONSTANT.COMMAND.CMD_EXIT_FILELIST ret=" + ret);
                notifyBusMessage(BUS_MESSAGE.BUS_EXIT_FILELIST, ret);
                break;
            }
            case CONSTANT.COMMAND.CMD_PAUSE_PLAYBACK: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';

                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_PAUSE, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_PAUSE_PLAYBACK ret=" + ret + "  name=" + name);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_PAUSE_PLAYBACK_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_PAUSE_PLAYBACK, ret);
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_RESUME_PLAYBACK: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                String name = new String(file.__name) + '\0';

                int ret = GKUSBSDK.GKUSB_FileControl(__hDevice, file.__type, GKUSBCommand.VIDEO_FILE_CONTROL.CONTROL_RESUM, name.getBytes());
                ZyLog.d("CONSTANT.COMMAND.CMD_RESUME_PLAYBACK ret=" + ret + "  name=" + name);
                if (ret == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_RESUME_PLAYBACK_ERR, new String(file.__name));
                } else {
                    notifyBusMessage(BUS_MESSAGE.BUS_RESUME_PLAYBACK, ret);
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_GET_PHOTO: {
                GKUSBFileInfo file = (GKUSBFileInfo) msg.message;
                byte[] bytes = file.__type == GKUSBCommand.FILE_TYPE.PHOTO_FILE ? file.__name : file.__thumb_name;
                if (bytes == null) {
                    break;
                }
                String name = new String(bytes) + '\0';
                GKUSBIFrame frame = new GKUSBIFrame();
                frame.__type = file.__type;
                int ret = GKUSBSDK.GKUSB_GetSmallPicture(__hDevice, frame.__type, name.getBytes(), frame);
                ZyLog.d("CONSTANT.COMMAND.CMD_GET_PHOTO ret=" + ret + "  name=" + name);
                if (frame.__type == GKUSBCommand.FILE_TYPE.PHOTO_FILE) {
                    if (ret != 0) {
//                        notifyBusMessage(BUS_MESSAGE.BUS_SMALL_PHOTO_ERR  , name);
                    } else {
                        Log.i("GKDevice", "get photo:" + frame.__iFrame[0] + " " + frame.__iFrame[1]);
                        CustomApp.__lruCacheHelper.putJpg(new String(file.__name), frame.__iFrame);
                        notifyBusMessage(BUS_MESSAGE.BUS_SMALL_PHOTO, new String(bytes));
                    }
                } else {
                    /*if (ret != 0) {
                        notifyBusMessage(BUS_MESSAGE.BUS_SMALL_VIDEO_THUMB_ERR , name);
                    } else {
                        GKFileIFrame iframe = new GKFileIFrame();
                        iframe.__name = name.getBytes();
                        iframe.__iFrame = frame.__iFrame;
                        iframe.__type = frame.__type;
                        iframe.__size = frame.__iFrame.length;
                        String decodecache = LruCacheHelper.getDiskCacheDirPathStr(CustomApp.customApp, "decodecache");
                        int i = GKPlayer.SGKS_Data2JPG(iframe.__iFrame, iframe, (decodecache +"\0").getBytes());
                        if(i == 1){
//                            notifyBusMessage(BUS_MESSAGE.BUS_SMALL_PHOTO, name);
                            CustomApp.__lruCacheHelper.put(new String(file.__thumb_name), BitmapFactory.decodeFile(decodecache+"/"+new String(file.__thumb_name)));
                        }else {
                            notifyBusMessage(BUS_MESSAGE.BUS_SMALL_VIDEO_THUMB_ERR , name);
                        }
                    }*/
                }
                break;
            }
            case CONSTANT.COMMAND.CMD_OPEN_RECORD: { // 开录像

                int status = GKUSBSDK.GKUSB_GetRecordStatus(__hDevice);
                ZyLog.d("CONSTANT.COMMAND.GKUSB_GetRecordStatus status=" + status);
                if (status == -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_SETRECORD_STATUS, -1); // status值-1表示失败
                    break;
                }
                int ret = 0;
                if (status != GKUSBCommand.STATUS_RECORD.RECORDING) {
                    PublicMethod.sleep(500);
                    ret = GKUSBSDK.GKUSB_SetRecordStatus(__hDevice, GKUSBCommand.STATUS_RECORD.RECORDING);
                }
                ZyLog.d("CONSTANT.COMMAND.GKUSB_SetRecordStatus ret=" + ret);
                if (ret == 0) {
                    int record_status = GKUSBSDK.GKUSB_GetRecordStatus(__hDevice);
                    ZyLog.d("CONSTANT.COMMAND.GKUSB_GetRecordStatus record_status=" + record_status);
                    if (record_status != -1) {
                        notifyBusMessage(BUS_MESSAGE.BUS_GETRECORD_STATUS, record_status);
                    }
                }
                notifyBusMessage(BUS_MESSAGE.BUS_SETRECORD_STATUS, ret); // ret为0成功，否则失败
                break;
            }

            case CONSTANT.COMMAND.CMD_SWITCH_CAMERA: {
                int ret = GKUSBSDK.GKUSB_SetLiveScreenStatus(__hDevice, (int) msg.message);
                notifyBusMessage(BUS_MESSAGE.BUS_SETRECORD_STATUS, ret);
                ZyLog.d("CONSTANT.COMMAND.CMD_SWITCH_CAMERA ret=" + ret);
            }
            default:
                break;
        }

    }

    // 普通指令发送线程
    private Runnable commandRunnable = new Runnable() {
        @Override
        public void run() {

            while (__bThreadStatus[CONSTANT.THREAD_ID.ID_CHECK_ONLINE]) {

                if (__hDevice == 0) {
                    PublicMethod.sleep(1);
                    continue;
                }

                // 设备发送指令
                __lock.lock();
                PublicMethod.sleep(50);
                HandleMessage(__gkusbCmdList.popFirstCmd());
                __lock.unlock();
                PublicMethod.sleep(1);
            }

            __lock.lock();
            __exit--;
            __lock.unlock();
            Log.i("GKDevice", "Exit command thread");
        }
    };

    // 设备状态检测线程
    private Runnable statusRunnable = new Runnable() {
        @Override
        public void run() {

            while (__bThreadStatus[CONSTANT.THREAD_ID.ID_CHECK_ONLINE]) {
                if (__hDevice == 0) {
                    PublicMethod.sleep(1);
                    continue;
                }

            /*    // 获取SD卡存在状态
                __lock.lock();
                PublicMethod.sleep(100);
                // TODO: 2017/4/24  仅发送  不发送无法拍照
                int sdcard_status = GKUSBSDK.GKUSB_GetCurrentStatus(__hDevice,
                        GKUSBCommand.STATUS_CONTROL.STATUS_SDCARD_EXSIT);
              *//*  if(sdcard_status != -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_SDCARD_EXSIT, sdcard_status);
                }else{
                    Log.i("sdcard", "sdcard exsit err");
                }*//*
                __lock.unlock();*/

                // 获取录像状态
                __lock.lock();
                PublicMethod.sleep(100); // 20170407155352
                int record_status = GKUSBSDK.GKUSB_GetRecordStatus(__hDevice);
                if (record_status != -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_GETRECORD_STATUS, record_status);
                }
                __lock.unlock();

                // 获取状态
                __lock.lock();
                PublicMethod.sleep(100); //
                int ret = GKUSBSDK.GKUSB_GetParam(__hDevice, GKUSBCommand.CMD_AUDIO_RECORD, null);
                if (ret != -1) {
                    notifyBusMessage(BUS_MESSAGE.BUS_GET_RECORD_AUDIO_PREVIEW, ret);
                }
                __lock.unlock();
                /*// 获取状态
                __lock.lock();
                PublicMethod.sleep(100); // 20170407155352
                GKUSBFile usbFile = new GKUSBFile();
                usbFile.__lock = GKUSBCommand.FILE_TYPE.PHOTO_FILE;
                usbFile.__command = GKUSBCommand.PHOTO_FILE_CONTROL.CONTROL_CAPTURE;
                String name = new String(usbFile.__name) + '\0';
                int ret1 = GKUSBSDK.GKUSB_GetControlResult(__hDevice, usbFile.__lock, usbFile.__command, name.getBytes());
                Log.i("GKDevice", "GKUSB_GetControlResult="+ret1);
                __lock.unlock();*/
                PublicMethod.sleep(2000);
            }

            __lock.lock();
            __exit--;
            __lock.unlock();
            Log.i("GKDevice", "Exit status thread");
        }
    };

    public void openStream() {
        if (__hDevice != 0) {
            sendCommand(CONSTANT.COMMAND.CMD_OPEN_STREAM, null);
        }
    }

    public void startStream() {
        if (__hDevice != 0) {
            sendCommand(CONSTANT.COMMAND.CMD_START_STREAM, null);
        }
    }

    public void stopStream() {
        if (__hDevice != 0) {
            sendCommand(CONSTANT.COMMAND.CMD_STOP_STREAM, null);
        }
    }
}
